Spring Boot项目根据model属性,排序拦截器

Author Avatar
zuoqy 8月 17, 2018
  • 在其它设备中阅读本文章

说明:此拦截器配置在pageHelper分页拦截器之前拦截,对model中字段进行排序。适应业务:对表格进行排序,可快速查找或对比数据。
图一.png

1.创建SortHelperAutoConfiguration.java SortInfo.java SortInterceptor.java

SortHelperAutoConfiguration.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Configuration;

import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;

import javax.annotation.PostConstruct;
import java.util.List;

@Configuration
@AutoConfigureAfter(PageHelperAutoConfiguration.class)
@ConditionalOnBean(SqlSessionFactory.class)

public class SortHelperAutoConfiguration {

@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;

@PostConstruct
public void addSortInterceptor() {
SortInterceptor interceptor = new SortInterceptor();

System.out.println("Sort Interceptor Config!!");

for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
sqlSessionFactory.getConfiguration().addInterceptor(interceptor);

}
}

}

SortInfo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SortInfo {

private String field;//排序字段
private String dir;//排序方向 desc(倒序) asc(正序)
private boolean isDbField = false;

public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
public boolean isDbField() {
return isDbField;
}
public void setDbField(boolean isDbField) {
this.isDbField = isDbField;
}
}

SortInterceptor.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;


@Intercepts(
{
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
}
)
public class SortInterceptor implements Interceptor{
@SuppressWarnings("rawtypes")
public static final ThreadLocal<SortInfo> localSort = new ThreadLocal<SortInfo>();

/**
* @Description: 开始排序
* @throws
*/
@SuppressWarnings("rawtypes")
public static void useSort(String field, String dir, boolean isDbField) {
SortInfo sort = new SortInfo();
sort.setDbField(isDbField);
sort.setDir(dir);
sort.setField(field);
localSort.set(sort);
}

@SuppressWarnings("rawtypes")
public static void useSort(String field, String dir) {
useSort(field, dir, false);
}

@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Object intercept(Invocation invocation) throws Throwable {

SortInfo sortInfo = localSort.get();

if (sortInfo == null) {
return invocation.proceed();
}

try{

Object[] args = invocation.getArgs();
MappedStatement ms = (MappedStatement) args[0];
Object parameter = args[1];
RowBounds rowBounds = (RowBounds) args[2];
ResultHandler resultHandler = (ResultHandler) args[3];
Executor executor = (Executor) invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;

if(args.length == 4){

boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {

cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}

String sql = boundSql.getSql();
String orderSql = buildOrderSql(sql, ms, sortInfo);

BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), orderSql, boundSql.getParameterMappings(), parameter);
List resultList = executor.query(ms, parameter, RowBounds.DEFAULT, resultHandler, cacheKey, newBoundSql);

return resultList;

}
catch(Throwable t)
{
localSort.remove();
throw t;
}


}

private String buildOrderSql(String sql, MappedStatement mappedStatement, SortInfo sortInfo){

StringBuilder pageSql = new StringBuilder(sql);
StringBuilder allSql = new StringBuilder();
allSql.append("select allpage.* from(").append(pageSql.toString()).append(") allpage");

String field = sortInfo.getField();
String dir = sortInfo.getDir();
if(dir == null){
dir = "";
}

if(sortInfo.isDbField() == false)
{
Map<String, String> map = buildFieldMapping(mappedStatement);
field = map.get(field);
}

if(field != null)
{
allSql.append(" order by allpage." + field + " " + dir + " ");
}

return allSql.toString();
}


private Map<String, String> buildFieldMapping(MappedStatement mappedStatement) {

ResultMap resultMap = mappedStatement.getResultMaps().get(0);
List<ResultMapping> mapping = resultMap.getResultMappings();

Map<String, String> mapper = new HashMap<String, String>();
for (ResultMapping mp : mapping) {
mapper.put(mp.getProperty(), mp.getColumn());

if(mp.getNestedResultMapId()!=null)
buildSubFieldMapping(mapper, mappedStatement, mp.getNestedResultMapId(), mp.getProperty());
}

return mapper;
}


private void buildSubFieldMapping(Map<String,String> mapper, MappedStatement mappedStatement, String id, String property) {

ResultMap resultMap = mappedStatement.getConfiguration().getResultMap(id);
if(resultMap==null)
return;

List<ResultMapping> mapping = resultMap.getResultMappings();
for (ResultMapping mp : mapping) {
mapper.put(property + "." + mp.getProperty(), mp.getColumn());

}
}


@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}


@Override
public void setProperties(Properties arg0) {
// TODO Auto-generated method stub

}
}

###2.在resource文件夹下创建文件夹META-INF

###3.在刚刚创建得META-INF文件夹下创建文件spring.factories
图二.png

使用方法:在对应需要排序得Service中调用方法SortInterceptor.useSort(sortField, sortDir);与pageHelper分页拦截器类似。


出自:zuoqy博客
如若转载请注明出处!